﻿using LaunchAllaround.Configuration;
using LaunchAllaround.DesignPattern;
using LaunchAllaround.DesignPattern.MVC;
using LaunchAllaround.Pad;
using System;
using System.Windows.Media;

namespace LaunchAllaround.Playlist
{
    [Serializable]
    public class PlaylistModel : Container<PadModel>, NamedModel<PlaylistModel>, Resettable<PlaylistModel>
    {
        public static readonly int MaxPadCount = 5;

        private static LaunchAllaround.Pad.Color[] defaultColors = { Colors.LightSkyBlue, Colors.Aquamarine, Colors.LightSeaGreen, Colors.LightCoral, Colors.LightSalmon };

        public PlaylistModel()
        {
            this.modelFunc = new NamedModelImpl<PlaylistModel>();

            PlaylistUI pui = new PlaylistUI(this);
            this.AddView(pui);
            PlaylistMenu pm = new PlaylistMenu(this);
            this.AddView(pm);
        }


        public PlaylistModel(PlaylistUI v)
        {
            this.modelFunc = new NamedModelImpl<PlaylistModel>();
            this.AddView(v);
            this.AddView(new PlaylistMenu(this));
        }

        public PlaylistModel(PlaylistMenu v)
        {
            this.modelFunc = new NamedModelImpl<PlaylistModel>();
            this.AddView(new PlaylistUI(this));
            this.AddView(v);
        }


        public override void Add(PadModel p)
        {
            if (this.Count == PlaylistModel.MaxPadCount)
            {
                throw new PadCountException();
            }
            p.Color = PlaylistModel.defaultColors[new Random().Next(PlaylistModel.defaultColors.Length)];
            base.Add(p);
            this.RefreshViews(new RefreshEvent<PlaylistModel>(this));
            Footer.myself.PrintInfo("Pad added");
        }

        public void ShiftFrom(int index)
        {
            Container<PadModel> tmp = this.GetRange(0, index);
            this.RemoveRange(0, index);
            this.AddRange(tmp);
            this.RefreshViews(new RefreshEvent<PlaylistModel>(this));
        }

        public override void Remove(PadModel item)
        {
            base.Remove(item);
            this.RefreshViews(new RefreshEvent<PlaylistModel>(this));
        }

        public override void Clear()
        {
            base.Clear();
            this.RefreshViews(new RefreshEvent<PlaylistModel>(this));
        }

        public override void RemoveAt(int i)
        {
            base.RemoveAt(i);
            this.RefreshViews(new RefreshEvent<PlaylistModel>(this));
            Footer.myself.PrintInfo("Pad removed");
        }

        public override void Insert(int i, PadModel item)
        {
            if (this.Count == PlaylistModel.MaxPadCount)
            {
                throw new PadCountException();
            }
            item.Color = PlaylistModel.defaultColors[this.Count % PlaylistModel.defaultColors.Length];
            base.Insert(i, item);
            this.RefreshViews(new RefreshEvent<PlaylistModel>(this));
        }


        // # Model Functionalities ######
        private NamedModelImpl<PlaylistModel> modelFunc;

        public void AddView(View<PlaylistModel> v)
        {
            this.modelFunc.AddView(v);
        }

        public Container<View<PlaylistModel>> GetViews()
        {
            return this.modelFunc.GetViews();
        }

        public void ClearViews()
        {
            this.modelFunc.ClearViews();
        }

        public void RefreshViews(RefreshEvent<PlaylistModel> ev)
        {
            this.modelFunc.RefreshViews(ev);
        }

        public void SetName(string name)
        {
            this.modelFunc.SetName(name);
            this.RefreshViews(new RefreshName<PlaylistModel>(this, this.GetName()));
        }

        public string GetName()
        {
            return this.modelFunc.GetName();
        }
        // ###############################

        public void Reset(PlaylistModel pattern)
        {
            base.Clear();
            for (int i = 0; i < pattern.Count; i++)
            {
                PadModel pm = new PadModel();
                this.Add(pm);
                pm.Reset(pattern.Get(i));
                this.RefreshViews(new RefreshEvent<PlaylistModel>(this));
            }
        }
    }
}
